/* Includes ------------------------------------------------------------------*/
#include <rtthread.h>

#include "stm32f1xx_hal.h"
#include "gpio.h"
#include "uart.h"

struct rt_semaphore sem;

#define MAXSEM     5

#define THREAD_STACK_SIZE 1024
#define THREAD_PRIORITY 8
#define THREAD_TIMESLICE 10

rt_uint32_t array[MAXSEM];

static rt_uint32_t set, get;



static rt_thread_t producer_tid = RT_NULL;
static rt_thread_t producer_tid1 = RT_NULL;
static rt_thread_t consumer_tid = RT_NULL;
static rt_thread_t consumer_tid1 = RT_NULL;

struct rt_semaphore sem_lock;

struct rt_semaphore sem_empty, sem_full;

/* éú2ú?? */
void producer_thread_entry(void* parameter)
{
    rt_int32_t cnt = 0;
    rt_int32_t no = (rt_uint32_t)parameter;
    /* ??DD100′? */
    while( cnt < 100)
    {
        /* ??è?ò??????? */
        rt_sem_take(&sem_empty, RT_WAITING_FOREVER);

        /* DT??array?úèY￡?é??? */
        rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
        array[set%MAXSEM] = cnt + 1;
        rt_kprintf("the producer %d generates a number: %d\n", 
            no,array[set%MAXSEM]);
        set++;
        rt_sem_release(&sem_lock);

        /* ·￠2?ò????ú?? */
        rt_sem_release(&sem_full);
        cnt++;

        /* ?Yí￡ò???ê±?? */
        rt_thread_delay(10);
    }

    rt_kprintf("the producer exit!\n");
}

void consumer_thread_entry(void* parameter)
{
    rt_uint32_t no;
    rt_uint32_t sum = 0;

    /* μún????3ì￡?óéè??ú2?êy′?μY??à′ */
    no = (rt_uint32_t)parameter;

    while(1)
    {
        /* ??μ?ò????ú?? */
        rt_sem_take(&sem_full, RT_WAITING_FOREVER);

        /* áù????￡?é?????DD2ù×÷ */
        rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
        sum += array[get%MAXSEM];
        rt_kprintf("the consumer[%d] get a number:%d\n", 
no, array[get%MAXSEM]);
        get++;
        rt_sem_release(&sem_lock);

        /* êí·?ò??????? */
        rt_sem_release(&sem_empty);

        /* éú3é??éú2úμ?100??êy??￡?í￡?1￡???·?????3ìí￡?1 */
        if (get == 100) break;

        /* DY?￠ò???ê±?? */
        rt_thread_delay(2000);
    }

    rt_kprintf("the consumer[%d] sum is %d \n ", no, sum);
    rt_kprintf("the consumer[%d] exit!\n");
}

int main()
{

    rt_sem_init(&sem_lock , "lock",   1,    RT_IPC_FLAG_FIFO);
    rt_sem_init(&sem_empty,"empty", MAXSEM, RT_IPC_FLAG_FIFO);
    rt_sem_init(&sem_full , "full",   0,   RT_IPC_FLAG_FIFO);

    
    producer_tid = rt_thread_create("producer",
        producer_thread_entry, 
        (void *)0, 
        THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
    if (producer_tid != RT_NULL)
        rt_thread_startup(producer_tid);
		/*
		producer_tid1 = rt_thread_create("producer1",
        producer_thread_entry, 
        (void *)1, 
        THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
    if (producer_tid1 != RT_NULL)
        rt_thread_startup(producer_tid1);
   */


    consumer_tid = rt_thread_create("consumer",
       consumer_thread_entry,/* ?????consumer_thread_entry */
        (void *)0, /* ?????RT_NULL */
        THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
    if (consumer_tid != RT_NULL)
        rt_thread_startup(consumer_tid);
		

    

	return 0;
}

